#pragma once
#include "acceptor.h"
#include "connection.h"
#include "eventloop.h"
#include "threadpool.h"
#include<map>
#include "epoll.h"
#include<memory>
#include<thread>
#include<mutex>

class Server
{
private:
    std::shared_ptr<EventLoop> mainReactor;     //只负责接受连接，然后分发给一个subReactor
    std::shared_ptr<Acceptor> acceptor;                     //连接接受器
    std::map<int, std::unique_ptr<Connection>> connections; //TCP连接
    std::vector<std::shared_ptr<EventLoop>> subReactors;    //负责处理事件循环
    std::shared_ptr<Epoll> ep;
    ThreadPool *thpool;     //线程池
public:
    Server(std::string ip, int port);
    ~Server();
    // void start(int);
    void start();
    void handleReadEvent(int);
    void newConnection(std::shared_ptr<Socket>);
    void deleteConnection(std::shared_ptr<Socket>);
};

Server::Server(std::string ip, int port) {
    ep = std::make_shared<Epoll>();
    mainReactor = std::make_shared<EventLoop>(ep);

    std::shared_ptr<Socket> serv_sock = std::make_shared<Socket>();
    std::shared_ptr<InetAddress> serv_addr = std::make_shared<InetAddress>("127.0.0.1", 12345);
    serv_sock->bind(serv_addr);
    serv_sock->listen();   

    acceptor = std::make_shared<Acceptor>(serv_sock, mainReactor);   //Acceptor由且只由mainReactor负责
    std::function<void()> accept_cb = std::bind(&Acceptor::acceptConnection, acceptor);
    Channel *mainCh = new Channel(ep, serv_sock->getFd(), EPOLLIN | EPOLLET, accept_cb);

    std::function<void(std::shared_ptr<Socket>)> cb = std::bind(&Server::newConnection, this, std::placeholders::_1);
    acceptor->setNewConnectionCallback(cb);
    mainCh->enableReading();

    int size = std::thread::hardware_concurrency();     //线程数量，也是subReactor数量
    thpool = new ThreadPool(size);      //新建线程池
    for(int i = 0; i < size; ++i){
        std::shared_ptr<Epoll> t_ep(ep);
        std::shared_ptr<EventLoop> sr = std::make_shared<EventLoop>(std::move(t_ep));
        subReactors.push_back(std::move(sr));     //每一个线程是一个EventLoop
    }

    for(int i = 0; i < size; ++i){
        std::function<void()> sub_loop = std::bind(&EventLoop::loop, subReactors[i]);
        thpool->add(sub_loop);      //开启所有线程的事件循环
    }
}

Server::~Server()
{
}

void Server::newConnection(std::shared_ptr<Socket> serv_sock){
    // 接受serv_sock上的客户端连接
    int random = serv_sock->getFd() % subReactors.size();    //调度策略：全随机
    std::unique_ptr<Connection> conn = std::make_unique<Connection>(ep, subReactors[random], serv_sock);   //分配给一个subReactor
    std::function<void(std::shared_ptr<Socket>)> delete_cb = std::bind(&Server::deleteConnection, this, std::placeholders::_1);
    conn->setDeleteConnectionCallback(delete_cb);
    connections.insert({serv_sock->getFd(), std::move(conn)});
}

void Server::deleteConnection(std::shared_ptr<Socket> sock){
    // 删除连接
}

void Server::start() {
    mainReactor->loop();
    std::mutex mtx;
    mtx.lock();
    mtx.lock();
}